/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2024-02-02
 * Time: 22:06
 *
 * https://www.nowcoder.com/share/jump/7745334641706885720057
 */
public class BM85 {

    private boolean isIPv4(String IP) {
        // 转义字符
        String[] nums = IP.split("\\.");
        // IPv4 必定分为 4 组
        if (nums.length != 4) {
            return false;
        }
        for (String num : nums) {
            // IPv4 地址内的数不会以 0 开头
            if (num.charAt(0) == '0' && num.length() > 1) {
                return false;
            }
            for (char c : num.toCharArray()) {
                if (c < '0' || c > '9') {
                    return false;
                }
            }
            // 范围为 0 - 255
            int val = Integer.parseInt(num);
            if (val < 0 || val > 255) {
                return false;
            }
        }
        return true;
    }

    private boolean isIpv6(String IP) {
        // limit 表示分出的组数
        // 正数，表示从左到右开始分割最多分出 n 组（最后一组全部包含进去，不再管后面的 regex）
        // 负数，表示从右到左开始，一致分组（即使有多个 :: 连续，也分出一个 ""）
        String[] nums = IP.split(":", -1);
        // IPv6 必定分为 8 组
        if (nums.length != 8) {
            return false;
        }
        for (String num : nums) {
            char[] s = num.toCharArray();
            // 可以以 0 开头的数字，字母可以使用大写，也可以是小写
            for (int i = 0; i < s.length; i++) {
                if (!(s[i] >= '0' && s[i] <= '9')
                        && !(s[i] >= 'A' && s[i] <= 'F')
                        && !(s[i] >= 'a' && s[i] <= 'f')) {
                    return false;
                }
            }
            // :: 分出的空
            if (s.length == 0) {
                return false;
            }
            // IPv6 地址中，多余的 0 也是不被允许的
            if (s[0] == '0' && s.length > 1 && s[1] == '0') {
                return false;
            }
        }
        return true;
    }

    public String solve(String IP) {
        if (isIPv4(IP)) {
            return "IPv4";
        } else if (isIpv6(IP)) {
            return "IPv6";
        } else {
            return "Neither";
        }
    }
}
